import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Map;

import com.speljohan.rsbot.bot.Bot;
import com.speljohan.rsbot.event.listeners.PaintListener;
import com.speljohan.rsbot.script.Constants;
import com.speljohan.rsbot.script.Script;
import com.speljohan.rsbot.script.wrappers.RSInterface;
import com.speljohan.rsbot.script.wrappers.RSItemTile;
import com.speljohan.rsbot.script.wrappers.RSNPC;
import com.speljohan.rsbot.script.wrappers.RSTile;

public class StrongholdSlaughter extends Script implements PaintListener {

	private String status = "";
	public long startTime = System.currentTimeMillis();
	public int strstartexp;
	public int attstartexp;
	public int defstartexp;
	public int rngstartexp;

	public boolean minotaur12 = false;
	public boolean minotaur27 = false;
	public boolean wolf = false;
	public boolean goblin5 = false;
	public boolean goblin13 = false;
	public boolean goblin11 = false;
	public boolean goblin16 = false;
	public boolean fleshcrawler28 = false;
	public boolean fleshcrawler35 = false;
	public boolean zombie444 = false;
	public boolean giantrat = false;

	public boolean emergencytele = false;
	public boolean b2p = false;
	public boolean ranges = false;

	// First Level ID's
	int gob5 = 4407;
	int gob13 = 4408;
	int gob11 = 4409;
	int gob16 = 4410;
	int mino12 = 4404;
	int mino27 = 4406;
	int wolff = 4413;

	// Second Level ID's
	int flesh28 = 4389;
	int flesh35 = 4390;
	int zombie44 = 4394;
	int bigrat = 4944;

	// Tab
	int TeleTab[] = { 8007, 8008, 8010 };
	int b2pTab = 8015;
	public int btpused;
	public int startpeaches;

	// Range Stuff
	private final int[] Arrows = { 882, 883, 884, 5616, 5617, 5622, 5623, 886,
			887, 5618, 5624, 888, 889, 5619, 5625, 7552, 7553, 890, 891, 5620,
			5626, 892, 893, 5621, 5627 };

	// Food Stuff
	int eatAt = 20;
	int escapeAt = 12;
	private final int[] FoodID = { 1895, 1893, 1891, 4293, 2142, 291, 2140,
			3228, 9980, 7223, 6297, 6293, 6295, 6299, 7521, 9988, 7228, 2878,
			7568, 2343, 1861, 13433, 315, 325, 319, 3144, 347, 355, 333, 339,
			351, 329, 3381, 361, 10136, 5003, 379, 365, 373, 7946, 385, 397,
			391, 3369, 3371, 3373, 2309, 2325, 2333, 2327, 2331, 2323, 2335,
			7178, 7180, 7188, 7190, 7198, 7200, 7208, 7210, 7218, 7220, 2003,
			2011, 2289, 2291, 2293, 2295, 2297, 2299, 2301, 2303, 1891, 1893,
			1895, 1897, 1899, 1901, 7072, 7062, 7078, 7064, 7084, 7082, 7066,
			7068, 1942, 6701, 6703, 7054, 6705, 7056, 7060, 2130, 1985, 1993,
			1989, 1978, 5763, 5765, 1913, 5747, 1905, 5739, 1909, 5743, 1907,
			1911, 5745, 2955, 5749, 5751, 5753, 5755, 5757, 5759, 5761, 2084,
			2034, 2048, 2036, 2217, 2213, 2205, 2209, 2054, 2040, 2080, 2277,
			2225, 2255, 2221, 2253, 2219, 2281, 2227, 2223, 2191, 2233, 2092,
			2032, 2074, 2030, 2281, 2235, 2064, 2028, 2187, 2185, 2229, 6883 };

	public void arrowpickup() {
		if (ranges == true && getMyPlayer().getInteracting() == null) {
			status = "Arrow Pickup";
			final RSItemTile Arrow = getGroundItemByID(Arrows);
			if (Arrow != null && !isInventoryFull()) {
				atTile(Arrow, "Take");
				wait(random(800, 900));
				clickInventoryArray(Arrows, "Wield");
			}
		}
	}

	public void B2P() {
		status = "B2P Time";
		if (skills.getCurrentSkillLevel(3) <= eatAt + random(-2, 2)
				&& b2p == true) {
			if (skills.getCurrentSkillLevel(3) <= eatAt + random(-2, 2)) {
				if (getInventoryCount(6833) >= 1) {
					atInventoryItem(6883, "eat");
					wait(random(1000, 2000));
				} else {
					log("Emergency tab time");
					atInventoryItem(b2pTab, "Break");
					wait(random(2000, 3000));
				}
				if (getInventoryCount(526) >= 10) {
					if (getInventoryCount(b2pTab) >= 1) {
						atInventoryItem(b2pTab, "Break");
						log("Used B2P Tab");
						wait(random(2000, 3000));
					} else {
						pickupbones();

					}
				}
			}
		}
	}

	public void checkHealth() {
		if (skills.getCurrentSkillLevel(3) <= eatAt + random(-2, 2)) {
			EatFood();
			B2P();
		}
	}

	// Methods
	private boolean clickInventoryArray(final int[] itemID, final String option) {
		if (getCurrentTab() != Constants.TAB_INVENTORY
				&& !RSInterface.getInterface(Constants.INTERFACE_BANK)
						.isValid()
				&& !RSInterface.getInterface(Constants.INTERFACE_STORE)
						.isValid()) {
			openTab(Constants.TAB_INVENTORY);
		}
		final int[] items = getInventoryArray();
		final java.util.List<Integer> possible = new ArrayList<Integer>();
		for (final int element : itemID) {
			for (int i = 0; i < items.length; i++) {
				if (items[i] == element) {
					possible.add(i);
				}
			}
		}
		if (possible.size() == 0) {
			return false;
		} else {
			final int IDE = random(0, possible.size());
			final int idx = possible.get(IDE);
			final Point t = getInventoryItemPoint(idx);
			clickMouse(t, 5, 5, false);
			return atMenu(option);
		}
	}

	public void EatFood() {
		if (getInventoryCount(FoodID) >= 1 && b2p == false) {
			clickInventoryArray(FoodID, "Eat");
			log("Eating Food");
		}
	}

	public void flesh28Attack() {
		status = "Finding NPC...";
		if (!getMyPlayer().isInCombat()
				&& getMyPlayer().getInteracting() == null
				&& fleshcrawler28 == true) {
			final RSNPC Crawler = getNearestFreeNPCByID(flesh28);
			if (Crawler != null) {
				atNPC(Crawler, "Attack");
				status = "Attacking NPC...";
			}
			wait(random(100, 200));
		}
	}

	public void flesh35Attack() {
		status = "Finding NPC...";
		if (!getMyPlayer().isInCombat()
				&& getMyPlayer().getInteracting() == null
				&& fleshcrawler35 == true) {
			final RSNPC Crawler = getNearestFreeNPCByID(flesh35);
			if (Crawler != null) {
				atNPC(Crawler, "Attack");
				status = "Attacking NPC...";
			}
			wait(random(100, 200));
		}
	}

	public String getAuthor() {
		return "Warbo66";
	}

	public String getName() {
		return "StrongholdSlaughter";
	}

	public String getScriptCategory() {
		return "Combat";
	}

	public String getScriptDescription() {
		String html = "<html>";
		html += "<body><center>";
		html += "<h2>" + getName() + "</h2></center>";
		html += "<b>Author: </b>" + getAuthor() + "<br>";
		html += "<b>Version: </b>" + getVersion() + "<br>";
		html += "<center>Start in the stonghold of security, near the NPC's you want to kill.<br></center>";
		html += "<b>Features:</b>"
				+ "<ul><li>Teleports Out Using Varrock, Camelot Or Lumbride Teleport Tabs When At Around 15 HP.</li>"
				+ "<li>Eats At 20HP.</li>"
				+ "<li>Works On First And Second Floor.</li>"
				+ "<li>Range Support</li>" + "<li>B2P Support</li>"
				+ "<li>Detailed Paint</li></ul>";
		html += "Food: <input type=\"radio\" name=\"how\" value=\"food\" checked=\"checked\"> B2P:<input type=\"radio\" name=\"how\" value=\"b2p\"><br />";
		html += "<center>If You Enable Emergency Teleporting Make Sure You Have Either A Varrock, Camelot Or Lumbridge Teletab In Inventory</center><br>";
		html += "<input type=checkbox name=teleport value=true> Disable Emergency Teleporting (Disable If Non Member, As You Do Not Have Acess To Teletabs.)</input><br>";
		html += "<input type=checkbox name=range value=true> Disable Range Support(Arrow Pickup)</input><br>";
		html += "Which Monster(The Number In Brackets Is The Monster Combat Level): <select name=\"monster\"><option selected>Minotaur(12)<option>Minotaur(27)<option>Minotaur(12) & Wolf(11)<option>Goblin(5)<option>Goblin(11)<option>Goblin(13)<option>Goblin(16)<option>Fleshcrawler(28)<option>Fleshcrawler(35)<option>Zombie(44)<option>Giant Rat(26)</select> <br><br>";
		html += "</body>";
		html += "</html>";
		return html;
	}

	public double getVersion() {
		return 0.7;
	}

	public void giantratAttack() {
		status = "Finding NPC...";
		if (!getMyPlayer().isInCombat()
				&& getMyPlayer().getInteracting() == null && giantrat == true) {
			final RSNPC Rat = getNearestFreeNPCByID(bigrat);
			if (Rat != null) {
				atNPC(Rat, "Attack");
				status = "Attacking NPC...";
			}
			wait(random(100, 200));
		}
	}

	public void goblin11Attack() {
		status = "Finding NPC...";
		if (!getMyPlayer().isInCombat()
				&& getMyPlayer().getInteracting() == null && goblin11 == true) {
			final RSNPC Goblin = getNearestFreeNPCByID(gob11);
			if (Goblin != null) {
				atNPC(Goblin, "Attack");
				status = "Attacking NPC...";
			}
			wait(random(100, 200));
		}
	}

	public void goblin13Attack() {
		status = "Finding NPC...";
		if (!getMyPlayer().isInCombat()
				&& getMyPlayer().getInteracting() == null && goblin13 == true) {
			final RSNPC Goblin = getNearestFreeNPCByID(gob13);
			if (Goblin != null) {
				atNPC(Goblin, "Attack");
				status = "Attacking NPC...";
			}
			wait(random(100, 200));
		}
	}

	public void goblin16Attack() {
		status = "Finding NPC...";
		if (!getMyPlayer().isInCombat()
				&& getMyPlayer().getInteracting() == null && goblin16 == true) {
			final RSNPC Goblin = getNearestFreeNPCByID(gob16);
			if (Goblin != null) {
				atNPC(Goblin, "Attack");
				status = "Attacking NPC...";
			}
			wait(random(100, 200));
		}
	}

	public void goblin5Attack() {
		status = "Finding NPC...";
		if (!getMyPlayer().isInCombat()
				&& getMyPlayer().getInteracting() == null && goblin5 == true) {
			final RSNPC Goblin = getNearestFreeNPCByID(gob5);
			if (Goblin != null) {
				atNPC(Goblin, "Attack");
				status = "Attacking NPC...";
			}
			wait(random(100, 200));
		}
	}

	public boolean inLumbridge() {
		if (distanceTo(new RSTile(3221, 3217)) <= 5) {
			log("We Are In Lumbridge, Logging Out!");
			logout();
			stopAllScripts();
			return true;
		} else {
			return false;
		}
	}

	public int loop() {
		mino12Attack();
		mino27Attack();
		wolfAttack();
		goblin5Attack();
		goblin13Attack();
		goblin11Attack();
		goblin16Attack();
		flesh28Attack();
		flesh35Attack();
		zombie44Attack();
		checkHealth();
		pickupbones();
		arrowpickup();
		return random(100, 200);
	}

	public void mino12Attack() {
		status = "Finding NPC...";
		if (!getMyPlayer().isInCombat()
				&& getMyPlayer().getInteracting() == null && minotaur12 == true) {
			final RSNPC Mino = getNearestFreeNPCByID(mino12);
			if (Mino != null) {
				atNPC(Mino, "Attack");
				status = "Attacking NPC...";
			}
			wait(random(100, 200));
		}
	}

	public void mino27Attack() {
		status = "Finding NPC...";
		if (!getMyPlayer().isInCombat()
				&& getMyPlayer().getInteracting() == null && minotaur27 == true) {
			final RSNPC Mino = getNearestFreeNPCByID(mino27);
			if (Mino != null) {
				atNPC(Mino, "Attack");
				status = "Attacking NPC...";
			}
			wait(random(100, 200));
		}
	}

	public void onFinish() {
		Bot.getEventManager().removeListener(PaintListener.class, this);
	}

	public void onRepaint(final Graphics g) {
		if (isLoggedIn()) {
			int strxpGained = 0;
			int attxpGained = 0;
			int defxpGained = 0;
			int rngxpGained = 0;
			btpused = startpeaches - getInventoryCount(b2pTab);
			if (strstartexp == 0) {
				strstartexp = skills
						.getCurrentSkillExp(Constants.STAT_STRENGTH);
			}
			if (attstartexp == 0) {
				attstartexp = skills.getCurrentSkillExp(Constants.STAT_ATTACK);
			}
			if (defstartexp == 0) {
				defstartexp = skills.getCurrentSkillExp(Constants.STAT_DEFENSE);
			}
			if (rngstartexp == 0) {
				rngstartexp = skills.getCurrentSkillExp(Constants.STAT_RANGE);
			}
			if (startpeaches == 0) {
				startpeaches = getInventoryCount(b2pTab);
			}
			strxpGained = skills.getCurrentSkillExp(Constants.STAT_STRENGTH)
					- strstartexp;
			defxpGained = skills.getCurrentSkillExp(Constants.STAT_DEFENSE)
					- defstartexp;
			attxpGained = skills.getCurrentSkillExp(Constants.STAT_ATTACK)
					- attstartexp;
			rngxpGained = skills.getCurrentSkillExp(Constants.STAT_RANGE)
					- rngstartexp;
			long millis = System.currentTimeMillis() - startTime;
			final long hours = millis / (1000 * 60 * 60);
			millis -= hours * 1000 * 60 * 60;
			final long minutes = millis / (1000 * 60);
			millis -= minutes * 1000 * 60;
			final long seconds = millis / 1000;
			g.setColor(new Color(60, 155, 200, 50));
			g.fill3DRect(4, 220, 150, 118, true);
			g.setColor(Color.white);
			g.drawString("B2P Used: " + btpused, 9, 331);
			g.drawString("Time running: " + hours + ":" + minutes + ":"
					+ seconds + ".", 9, 315);
			g.drawString("Status: " + status, 9, 299);
			g.drawString("Attack XP Gained: " + attxpGained, 9, 283);
			g.drawString("Strength XP Gained: " + strxpGained, 9, 267);
			g.drawString("Defence XP Gained: " + defxpGained, 9, 251);
			g.drawString("Range XP Gained: " + rngxpGained, 9, 235);
		}
	}

	public boolean onStart(final Map<String, String> args) {
		status = "Starting Up...";
		if (args.get("how").equals("b2p")) {
			b2p = true;
		} else {
			b2p = false;
		}
		if (args.get("teleport") == null) {
			emergencytele = true;
			log("Teleporting Enabled");
		} else {
			emergencytele = false;
			log("Teleporting Disabled.");
		}
		if (args.get("range") == null) {
			ranges = true;
			log("Range Support Enabled");
		} else {
			ranges = false;
			log("Range Support Disabled.");
		}
		if (args.get("monster").equals("Minotaur(12)")) {
			minotaur12 = true;
		}
		if (args.get("monster").equals("Minotaur(27)")) {
			minotaur27 = true;
		}
		if (args.get("monster").equals("Minotaur(12) & Wolf(11)")) {
			minotaur12 = true && wolf == true;
		}
		if (args.get("monster").equals("Wolf(11)")) {
			wolf = true;
		}
		if (args.get("monster").equals("Goblin(5)")) {
			goblin5 = true;
		}
		if (args.get("monster").equals("Goblin(11)")) {
			goblin11 = true;
		}
		if (args.get("monster").equals("Goblin(13)")) {
			goblin13 = true;
		}
		if (args.get("monster").equals("Goblin(16)")) {
			goblin13 = true;
		}
		// Second Level
		if (args.get("monster").equals("Fleshcrawler(28)")) {
			fleshcrawler28 = true;
		}
		if (args.get("monster").equals("Fleshcrawler(35)")) {
			fleshcrawler35 = true;
		}
		if (args.get("monster").equals("Zombie(44)")) {
			zombie444 = true;
		}
		if (args.get("monster").equals("Giant Rat(26)")) {
			giantrat = true;
		}
		return true;
	}

	public void pickupbones() {
		if (b2p == true && getMyPlayer().getInteracting() == null) {
			status = "Taking Bones";
			final RSItemTile Bone = getGroundItemByID(526);
			if (Bone != null && !isInventoryFull()) {
				atTile(Bone, "Take Bones");
				wait(random(800, 900));
			}
		}
	}

	public void wolfAttack() {
		status = "Finding NPC...";
		if (!getMyPlayer().isInCombat()
				&& getMyPlayer().getInteracting() == null && wolf == true) {
			final RSNPC Wolf = getNearestFreeNPCByID(wolff);
			if (Wolf != null) {
				atNPC(Wolf, "Attack");
				status = "Attacking NPC...";
			}
			wait(random(100, 200));
		}
	}

	public void zombie44Attack() {
		status = "Finding NPC...";
		if (!getMyPlayer().isInCombat()
				&& getMyPlayer().getInteracting() == null && zombie444 == true) {
			final RSNPC Zombie = getNearestFreeNPCByID(zombie44);
			if (Zombie != null) {
				atNPC(Zombie, "Attack");
				status = "Attacking NPC...";
			}
			wait(random(100, 200));
		}
	}

}